﻿using System;
using System.ComponentModel;



namespace DiscoveryLogic.DataServices.DataSources
{


    public enum AccountType
    {
        Savings = 0,
        CreditCard = 1,
        Mortgage = 2,
        Plan401k = 3,
        FiveTwoNine = 4,
        Investments = 5,
        Checking = 6,
        RetirementPlanner = 7,
        TradeHistory = 8
    }; 


    
    public class Account : INotifyPropertyChanged
    {
        #region Private Variables

            private int id;
            private string name;
            private string accountNumber;
            private AccountType type;
            private double balance;
            private double minimumPayment;
            private DateTime nextPaymentDueDate;
            private double nextPaymentAmount;
            private string visualPath;
            private DateTime lastTransactionDate;
            private double lastTransactionAmount;

        #endregion

        #region Get/Set Properties

            public int Id
        {
            get { return id; }
            set {

                if (id != value)
                {
                    id = value;
                    Notify();
                    OnPropertyChanged(new PropertyChangedEventArgs("Id"));
                }
            }
        }

            public string Name
            {
                get { return name; }
                set
                {
                    if (name != value)
                    {
                        name = value;
                        Notify();
                        OnPropertyChanged(new PropertyChangedEventArgs("Name"));

                    }
                }
            }

            public string AccountNumber
            {
                get { return accountNumber; }
                set
                {
                    if (accountNumber != value)
                    {
                        accountNumber = value;
                        Notify();
                        OnPropertyChanged(new PropertyChangedEventArgs("AccountNumber"));

                    }
                }
            }

            public AccountType Type
            {
                get { return type; }
                set { 
                    if(type != value)
                    {
                        type = value;
                        Notify();
                        OnPropertyChanged(new PropertyChangedEventArgs("Type"));

                    }
                }
            }

            public double Balance
            {
                get { return balance; }
                set
                {
                    if (balance != value)
                    {
                        balance = value;
                        Notify();

                        OnPropertyChanged(new PropertyChangedEventArgs("Balance"));
                    }
                }
            }

            public double MinimumPayment
            {
                get { return minimumPayment; }
                set {
                    if (minimumPayment != value)
                    {
                        minimumPayment = value;
                        Notify();
                        OnPropertyChanged(new PropertyChangedEventArgs("MinimumPayment"));
                    }
                }
            }

            public DateTime NextPaymentDueDate
            {
                get { return nextPaymentDueDate; }
                set {
                    if (nextPaymentDueDate != value)
                    {
                        nextPaymentDueDate = value;
                        Notify();
                        OnPropertyChanged(new PropertyChangedEventArgs("NextPaymentDueDate"));
                    }
                }
            }

            public double NextPaymentAmount
            {
                get { return nextPaymentAmount; }
                set {
                    if (nextPaymentAmount != value)
                    {
                        nextPaymentAmount = value;
                        Notify();
                        OnPropertyChanged(new PropertyChangedEventArgs("NextPaymentAmount"));
                    }
                }
            }

            public string VisualPath
            {
                get { return visualPath; }
                set
                {
                    if (visualPath != value)
                    {
                        visualPath = value;
                        Notify();
                        OnPropertyChanged(new PropertyChangedEventArgs("VisualPath"));
                    }
                }
            }

            public DateTime LastTransactionDate
            {
                get { return lastTransactionDate; }
                set
                {
                    if (lastTransactionDate != value)
                    {
                        lastTransactionDate = value;
                        OnPropertyChanged(new PropertyChangedEventArgs("LastTransactionDate"));
                    }
                }
            }

            public double LastTransactionAmount
            {
                get { return lastTransactionAmount; }
                set
                {
                    if (lastTransactionAmount != value)
                    {
                        lastTransactionAmount = value;
                        OnPropertyChanged(new PropertyChangedEventArgs("LastTransactionAmount"));
                    }
                }
            }


        #endregion

        #region Constructors

            public Account():this(0,string.Empty,AccountType.Savings,0,0,DateTime.MaxValue,0)
            {

            }
            
            public Account(int id,
                string accountNumber,
                AccountType type,
                double balance,
                double minimumPayment,
                DateTime nextPaymentDueDate,
                double nextPaymentAmount
                )
            {
                this.id = id;
                this.accountNumber = accountNumber;
                this.type = type;
                this.balance = balance;
                this.minimumPayment = minimumPayment;
                this.nextPaymentDueDate = nextPaymentDueDate;
                this.nextPaymentAmount = nextPaymentAmount;
            }

            public Account(int id,
                string name,
                string accountNumber,
                AccountType type,
                double balance,
                double minimumPayment,
                DateTime nextPaymentDueDate,
                double nextPaymentAmount,
                string visualPath,
                DateTime lastTransactionDate,
                double lastTransactionAmount
                )
            {
                this.id = id;
                this.name = name;
                this.accountNumber = accountNumber;
                this.type = type;
                this.balance = balance;
                this.minimumPayment = minimumPayment;
                this.nextPaymentDueDate = nextPaymentDueDate;
                this.nextPaymentAmount = nextPaymentAmount;
                this.visualPath = visualPath;
                this.lastTransactionDate = lastTransactionDate;
                this.lastTransactionAmount = lastTransactionAmount;
            }

        #endregion

        // A delegate type for hooking up change notifications.
        public delegate void DetailChangedEventHandler(object sender, EventArgs e); // An event that clients can use to be notified whenever the

        // elements of the list change.
        public event DetailChangedEventHandler DetailChanged;

        // Invoke the Changed event; called whenever list changes
        protected virtual void OnDetailChanged(EventArgs e)
        {
            if (DetailChanged != null)
                DetailChanged(this, e);
        }

        protected void Notify()
        {
            EventArgs args = new EventArgs();
            OnDetailChanged(args);
        }


        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, args); 
            }
        }

        #endregion
    }
}
